From 144c695d7424f307484286ef1ccc6ebaceb280d7 Mon Sep 17 00:00:00 2001 From: Tim Deegan Date: Fri, 27 Apr 2007 10:24:09 +0100 Subject: [PATCH] [XEN] Replace IS_COMPAT() in the shadow code with pv_32on64_*() which test for the actual case we're interested in (PV PAE pagetables disguised as 64bit ones by the compat mm code). Signed-off-by: Tim Deegan --- xen/arch/x86/mm/shadow/common.c | 11 ++++++----- xen/arch/x86/mm/shadow/multi.c | 35 ++++++++++++++------------------- 2 files changed, 21 insertions(+), 25 deletions(-) diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c index 1b8d04b76c..307c06d7cf 100644 --- a/xen/arch/x86/mm/shadow/common.c +++ b/xen/arch/x86/mm/shadow/common.c @@ -1577,9 +1577,7 @@ void sh_destroy_shadow(struct vcpu *v, mfn_t smfn) t == SH_type_fl1_pae_shadow || t == SH_type_fl1_64_shadow || t == SH_type_monitor_table || -#ifdef CONFIG_COMPAT - (IS_COMPAT(v->domain) && t == SH_type_l4_64_shadow) || -#endif + (pv_32on64_vcpu(v) && t == SH_type_l4_64_shadow) || (page_get_owner(mfn_to_page(_mfn(sp->backpointer))) == v->domain)); @@ -1622,7 +1620,7 @@ void sh_destroy_shadow(struct vcpu *v, mfn_t smfn) SHADOW_INTERNAL_NAME(sh_destroy_l1_shadow, 4, 4)(v, smfn); break; case SH_type_l2h_64_shadow: - ASSERT( IS_COMPAT(v->domain) ); + ASSERT(pv_32on64_vcpu(v)); /* Fall through... */ case SH_type_l2_64_shadow: SHADOW_INTERNAL_NAME(sh_destroy_l2_shadow, 4, 4)(v, smfn); @@ -2716,7 +2714,10 @@ static int shadow_log_dirty_enable(struct domain *d) } #if (SHADOW_OPTIMIZATIONS & SHOPT_LINUX_L3_TOPLEVEL) - if ( IS_COMPAT(d) ) + /* 32bit PV guests on 64bit xen behave like older 64bit linux: they + * change an l4e instead of cr3 to switch tables. Give them the + * same optimization */ + if ( pv_32on64_domain(d) ) d->arch.paging.shadow.opt_flags = SHOPT_LINUX_L3_TOPLEVEL; #endif diff --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c index 7002f02567..c143cc34c8 100644 --- a/xen/arch/x86/mm/shadow/multi.c +++ b/xen/arch/x86/mm/shadow/multi.c @@ -134,9 +134,8 @@ set_shadow_status(struct vcpu *v, mfn_t gmfn, u32 shadow_type, mfn_t smfn) d->domain_id, v->vcpu_id, mfn_x(gmfn), shadow_type, mfn_x(smfn)); -#ifdef CONFIG_COMPAT - if ( !IS_COMPAT(d) || shadow_type != SH_type_l4_64_shadow ) -#endif + /* 32-on-64 PV guests don't own their l4 pages so can't get_page them */ + if ( !pv_32on64_vcpu(v) || shadow_type != SH_type_l4_64_shadow ) { res = get_page(mfn_to_page(gmfn), d); ASSERT(res == 1); @@ -162,9 +161,8 @@ delete_shadow_status(struct vcpu *v, mfn_t gmfn, u32 shadow_type, mfn_t smfn) v->domain->domain_id, v->vcpu_id, mfn_x(gmfn), shadow_type, mfn_x(smfn)); shadow_hash_delete(v, mfn_x(gmfn), shadow_type, smfn); -#ifdef CONFIG_COMPAT - if ( !IS_COMPAT(v->domain) || shadow_type != SH_type_l4_64_shadow ) -#endif + /* 32-on-64 PV guests don't own their l4 pages; see set_shadow_status */ + if ( !pv_32on64_vcpu(v) || shadow_type != SH_type_l4_64_shadow ) put_page(mfn_to_page(gmfn)); } @@ -746,7 +744,8 @@ _sh_propagate(struct vcpu *v, // PV guests in 64-bit mode use two different page tables for user vs // supervisor permissions, making the guest's _PAGE_USER bit irrelevant. // It is always shadowed as present... - if ( (GUEST_PAGING_LEVELS == 4) && !IS_COMPAT(d) && !is_hvm_domain(d) ) + if ( (GUEST_PAGING_LEVELS == 4) && !pv_32on64_domain(d) + && !is_hvm_domain(d) ) { sflags |= _PAGE_USER; } @@ -1300,7 +1299,7 @@ do { \ for ( _i = 0; _i < SHADOW_L2_PAGETABLE_ENTRIES; _i++ ) \ { \ if ( (!(_xen)) \ - || !IS_COMPAT(_dom) \ + || !pv_32on64_domain(_dom) \ || mfn_to_shadow_page(_sl2mfn)->type != SH_type_l2h_64_shadow \ || (_i < COMPAT_L2_PAGETABLE_FIRST_XEN_SLOT(_dom)) ) \ { \ @@ -1411,7 +1410,7 @@ void sh_install_xen_entries_in_l4(struct vcpu *v, mfn_t gl4mfn, mfn_t sl4mfn) __PAGE_HYPERVISOR); } - if ( IS_COMPAT(v->domain) ) + if ( pv_32on64_domain(v->domain) ) { /* install compat arg xlat entry */ sl4e[shadow_l4_table_offset(COMPAT_ARG_XLAT_VIRT_BASE)] = @@ -1437,7 +1436,7 @@ static void sh_install_xen_entries_in_l2h(struct vcpu *v, mfn_t sl2hmfn) int i; #else - if ( !pv_32bit_vcpu(v) ) + if ( !pv_32on64_vcpu(v) ) return; #endif @@ -1622,9 +1621,6 @@ sh_make_shadow(struct vcpu *v, mfn_t gmfn, u32 shadow_type) #endif #if CONFIG_PAGING_LEVELS >= 3 && GUEST_PAGING_LEVELS >= 3 case SH_type_l2h_shadow: -#ifdef CONFIG_COMPAT - ASSERT( IS_COMPAT(v->domain) ); -#endif sh_install_xen_entries_in_l2h(v, smfn); break; #endif #if CONFIG_PAGING_LEVELS == 2 && GUEST_PAGING_LEVELS == 2 @@ -1685,7 +1681,7 @@ sh_make_monitor_table(struct vcpu *v) l4e = sh_map_domain_page(m4mfn); l4e[0] = l4e_from_pfn(mfn_x(m3mfn), __PAGE_HYPERVISOR); sh_unmap_domain_page(l4e); - if ( pv_32bit_vcpu(v) ) + if ( pv_32on64_vcpu(v) ) { // Install a monitor l2 table in slot 3 of the l3 table. // This is used for all Xen entries. @@ -1840,13 +1836,12 @@ static shadow_l2e_t * shadow_get_and_create_l2e(struct vcpu *v, shadow_l3e_t new_sl3e; unsigned int t = SH_type_l2_shadow; -#ifdef CONFIG_COMPAT /* Tag compat L2 containing hypervisor (m2p) mappings */ - if ( IS_COMPAT(v->domain) && + if ( pv_32on64_domain(v->domain) && guest_l4_table_offset(gw->va) == 0 && guest_l3_table_offset(gw->va) == 3 ) t = SH_type_l2h_shadow; -#endif + /* No l2 shadow installed: find and install it. */ *sl2mfn = get_shadow_status(v, gw->l2mfn, t); if ( !mfn_valid(*sl2mfn) ) @@ -2111,7 +2106,7 @@ void sh_destroy_monitor_table(struct vcpu *v, mfn_t mmfn) l4_pgentry_t *l4e = sh_map_domain_page(mmfn); ASSERT(l4e_get_flags(l4e[0]) & _PAGE_PRESENT); m3mfn = _mfn(l4e_get_pfn(l4e[0])); - if ( pv_32bit_vcpu(v) ) + if ( pv_32on64_vcpu(v) ) { /* Need to destroy the l2 monitor page in slot 3 too */ l3_pgentry_t *l3e = sh_map_domain_page(m3mfn); @@ -3474,7 +3469,7 @@ sh_update_cr3(struct vcpu *v, int do_locking) (unsigned long)pagetable_get_pfn(v->arch.guest_table)); #if GUEST_PAGING_LEVELS == 4 - if ( !(v->arch.flags & TF_kernel_mode) && !IS_COMPAT(v->domain) ) + if ( !(v->arch.flags & TF_kernel_mode) && !pv_32on64_vcpu(v) ) gmfn = pagetable_get_mfn(v->arch.guest_table_user); else #endif @@ -4285,7 +4280,7 @@ int sh_audit_l3_table(struct vcpu *v, mfn_t sl3mfn, mfn_t x) mfn = shadow_l3e_get_mfn(*sl3e); gmfn = get_shadow_status(v, audit_gfn_to_mfn(v, gfn, gl3mfn), ((GUEST_PAGING_LEVELS == 3 || - IS_COMPAT(v->domain)) + pv_32on64_vcpu(v)) && !shadow_mode_external(v->domain) && (guest_index(gl3e) % 4) == 3) ? SH_type_l2h_shadow -- 2.30.2